#pragma once
#include <memory>
#include "Socket.hpp"
#include "Channel.hpp"
#include "EventLoop.hpp"

class Acceptor
{
private:
    Socket _socket;
    EventLoop *_loop;
    Channel _channel;

    using AcceptorCallback = std::function<void(int)>;
    AcceptorCallback _accept_callback;

    void HandlerRead()
    {
        int newfd = _socket.Accept();
        if (newfd < 0)
            return;
        if (_accept_callback)
            _accept_callback(newfd);
    }

    int CreateServer(int port)
    {
        assert(_socket.CreateServer(port));
        return _socket.Fd();
    }

public:
    Acceptor(EventLoop *loop, int port) : _socket(CreateServer(port)), _loop(loop),
                                          _channel(loop, _socket.Fd())
    {
        _channel.SetReadCallback(std::bind(&Acceptor::HandlerRead, this));
    }
    ~Acceptor() {}

    void SetAcceptCallback(const AcceptorCallback &cb) { _accept_callback = cb; }

    void Listen() { _channel.EnableRead(); }
};